package com.by.course.controller.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.fastjson.JSON;
import com.by.course.config.web.jwt.JwtService;
import com.by.course.config.web.jwt.PassToken;
import com.by.course.entity.base.BaseResult;
import com.by.course.entity.vo.wx.req.WxOrder;
import com.by.course.entity.vo.wx.resp.OrderResultVO;
import com.by.course.entity.vo.wx.resp.PayResultVO;
import com.by.course.entity.vo.wx.resp.WxCodeResultVO;
import com.by.course.entity.vo.wx.resp.WxPhoneNumberResultVO;
import com.by.course.utils.WxPayUtil;
import com.github.binarywang.wxpay.service.WxPayService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 微信相关接口
 *
 * @author zhd
 * @date 2023/07/08 14:59
 **/
@Slf4j
@RestController
@RequestMapping("/wx")
@Api(tags = "微信接口")
public class WxController {

    /**
     * 有效期一天
     */
    private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000L;

    @Resource
    private WxMaService wxMaService;

    @Resource
    private JwtService jwtService;

    @Resource
    private WxPayUtil wxPayUtil;

    @Resource
    private WxPayService wxPayService;

    @Resource
    private ThreadPoolTaskExecutor proxyExecutor;

    private ReentrantLock lock = new ReentrantLock();

    @ApiOperation("验证Token")
    @PostMapping(value = "/verify")
    @ResponseBody
    @PassToken
    @Cacheable(cacheNames = "verifyToken", key = "'verifyToken_' + #token", cacheManager = "caffeineCacheManager")
    public BaseResult<Boolean> verifyToken(@RequestParam(required = false) String token) {
        if (StringUtils.isBlank(token)) {
            return new BaseResult.Builder<Boolean>().setData(false).build();
        }
        Claims claims = null;
        try {
            claims = jwtService.verifyJwt(token);
        } catch (Exception e) {
            log.error("verifyToken error", e);
        }
        if (claims == null) {
            return new BaseResult.Builder<Boolean>().setData(false).build();
        }
        boolean after = claims.getExpiration().after(new Date());
        return new BaseResult.Builder<Boolean>().setData(after).build();
    }

    @ApiOperation("通过微信的临时码获取appId等信息")
    @PostMapping(value = "/getOpenid")
    @ResponseBody
    public BaseResult<WxCodeResultVO> wechatSession(@RequestParam String code, @RequestParam(required = false) String token) throws WxErrorException {
//        if (StringUtils.isNotBlank(token)) {
//            Claims claims = null;
//            try {
//                claims = jwtService.verifyJwt(token);
//            } catch (Exception e) {
//                log.error("verifyToken error", e);
//            }
//            if (claims != null && claims.getExpiration().after(new Date())) {
//                Long userId = claims.get("userId", Long.class);
//                String openId = claims.get("openId", String.class);
//                WxCodeResultVO resultVO = WxCodeResultVO.builder()
//                        .openid(openId)
//                        .access_token(token)
//                        .user_id(userId)
//                        .build();
//                return new BaseResult.Builder<WxCodeResultVO>().setData(resultVO).build();
//            }
//        }
//        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
//        if (sessionInfo == null) {
//            throw new BusinessException("获取微信信息失败");
//        }
//        WxCodeResultVO resultVO = WxCodeResultVO.builder()
//                .sessionKey(sessionInfo.getSessionKey())
//                .openid(sessionInfo.getOpenid())
//                .user_id(0L)
//                .build();
//        List<BaseUserWx> baseUserWxList = baseUserWxMapper.selectWxByOpenId(sessionInfo.getOpenid());
//        if (CollUtil.isNotEmpty(baseUserWxList)) {
//            BaseUserWx baseUserWx = baseUserWxList.get(0);
//            log.info("WxController baseUserWx userId:{}, openId:{}", baseUserWx.getUserId(), baseUserWx.getOpenid());
//            Long userId = baseUserWx.getUserId();
//            BaseUser baseUser = baseUserMapper.selectById(userId);
//            if (baseUser == null) {
//                throw new BusinessException("wx exit, user not exit " + baseUserWx.getOpenid());
//            }
//            log.info("WxController.baseUser userId:{}, phoneNumber:{}", baseUser.getId(), baseUser.getMobilePhone());
//            resultVO.setUser_id(userId);
//            String jwt = jwtService.getJwt(userId, sessionInfo.getOpenid());
//            resultVO.setAccess_token(jwt);
//            resultVO.setAccess_token_expire_time(System.currentTimeMillis() + EXPIRATION_TIME);
//            resultVO.setUser_id(userId);
//            resultVO.setQrcode(baseUser.getQrcode());
//            resultVO.setRoleId(baseUser.getRoleId());
//        }
//        log.info("WxController.wechatSession resultVO:{}", JSON.toJSONString(resultVO));
        return new BaseResult.Builder<WxCodeResultVO>().setData(null).build();
    }

    @ApiOperation("获取手机号码")
    @PostMapping("/getPhoneNumber")
    @ResponseBody
    public BaseResult<WxPhoneNumberResultVO> getPhoneNumber(@RequestParam String code, @RequestParam String openId) throws WxErrorException, IOException {
//        WxMaPhoneNumberInfo newPhoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(code);
//        if (newPhoneNoInfo == null || StringUtils.isBlank(newPhoneNoInfo.getPhoneNumber())) {
//            throw new BusinessException("获取微信手机号码失败 " + openId);
//        }
//        WxPhoneNumberResultVO resultVO = new WxPhoneNumberResultVO();
//        resultVO.setMobilePhone(newPhoneNoInfo.getPhoneNumber());
//        BaseUser baseUser = baseUserMapper.selectByPhone(newPhoneNoInfo.getPhoneNumber());
//        if (baseUser != null) {
//            baseUserService.updateFillUserInfo(baseUser, resultVO, openId);
//            resultVO.setRoleId(baseUser.getRoleId());
//        } else {
//            baseUserService.createNewUserInfo(resultVO, openId);
//        }
        log.info("WxController.getPhoneNumber openId:{} resultVO:{}", openId, JSON.toJSONString(null));
        return new BaseResult.Builder<WxPhoneNumberResultVO>().setData(null).build();
    }


    @ApiOperation("微信支付")
    @PostMapping("/wxPay")
    @ResponseBody
    public BaseResult<PayResultVO> wxPay(@RequestBody WxOrder wxOrder) {
//        log.info("WxController.wxPay wxOrder:{}", JSON.toJSONString(wxOrder));
//        WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = null;
//        try {
//            jsapiResult = wxPayUtil.testUnifiedOrderV3(wxOrder);
//        } catch (WxPayException e) {
//            e.printStackTrace();
//        }
//        if (jsapiResult == null) {
//            throw new BusinessException("微信支付失败");
//        }
//        log.info("{}", JSON.toJSONString(jsapiResult));
//        PayResultVO vo = new PayResultVO();
//        BeanUtils.copyProperties(jsapiResult, vo);
        return new BaseResult.Builder<PayResultVO>().setData(null).build();
    }

    @ApiOperation("微信支付结果通知")
    @PostMapping("/wxPayResult")
    @ResponseBody
    public BaseResult<String> wxPayResult(@RequestBody String wxOrder, HttpServletRequest request) {
//        try {
//            String timestamp = request.getHeader("Wechatpay-Timestamp");
//            String nonce = request.getHeader("Wechatpay-Nonce");
//            String serialNo = request.getHeader("Wechatpay-Serial");
//            String signature = request.getHeader("Wechatpay-Signature");
//            WxPayOrderNotifyV3Result wxPayOrderNotifyResult = wxPayService.parseOrderNotifyV3Result(wxOrder,
//                    new SignatureHeader(timestamp, nonce, signature, serialNo));
//            log.info("wxPayResult: {}", JSON.toJSONString(wxPayOrderNotifyResult));
//            if (wxPayOrderNotifyResult != null
//                    && wxPayOrderNotifyResult.getResult() != null
//                    && "SUCCESS".equals(wxPayOrderNotifyResult.getResult().getTradeState())) {
//                WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyResult.getResult();
//                String outTradeNo = wxPayOrderNotifyResult.getResult().getOutTradeNo();
//                String[] s = outTradeNo.split("_");
//                Long id = Long.valueOf(s[0]);
//                BaseWxOrder order = baseWxOrderService.getById(id);
//                order.setMchid(result.getMchid());
//                order.setTotal(String.valueOf(result.getAmount().getTotal() / 100));
//                order.setPayerTotal(String.valueOf(result.getAmount().getPayerTotal() / 100));
//                order.setStatus(2);
//                order.setTransactionId(result.getTransactionId());
//                order.setSuccessTime(result.getSuccessTime());
//                baseWxOrderService.updateById(order);
//
//                // 购买者个人信息
//                BaseUser baseUser = baseUserMapper.selectById(order.getUserId());
//                MedicalMembershipCard membershipCard = medicalMembershipCardMapper.selectById(order.getUserOrderId());
//                if (membershipCard == null || baseUser == null) {
//                    throw new BusinessException("BaseUserServiceImpl.dealThreeAgent 信息不存在:" + JSON.toJSONString(order));
//                }
//
//                if (membershipCard.getType() == 3) {
//                    lock.lock();
//                    try {
//                        List<ThirdCode> thirdCodes = thirdCodeMapper.listByCardId(membershipCard.getId());
//                        if (CollUtil.isNotEmpty(thirdCodes)) {
//                            ThirdCode thirdCode = thirdCodes.get(0);
//                            String thirdCodeCopy = baseUser.getThirdCode();
//                            if (StrUtil.isNotBlank(thirdCodeCopy)) {
//                                thirdCodeCopy = thirdCodeCopy + "," + thirdCode.getCode();
//                            } else {
//                                thirdCodeCopy = thirdCode.getCode();
//                            }
//                            baseUserMapper.updateThirdCode(baseUser.getId(), thirdCodeCopy);
//                            thirdCode.setStatus(1);
//                            thirdCode.setUserId(baseUser.getId());
//                            thirdCodeMapper.updateByPrimaryKeySelective(thirdCode);
//                        } else {
//                            log.warn("no third code to buy:{}", id);
//                        }
//                    } finally {
//                        lock.unlock();
//                    }
//                    return new BaseResult.Builder<String>().build();
//                }
//
//                // 处理代理逻辑
//                proxyExecutor.execute(() -> {
//                    try {
//                        baseUserService.dealThreeAgent(order);
//                    } catch (Exception e) {
//                        log.error("WxController.wxPayResult error wxOrder:{}", wxOrder, e);
//                    }
//                });
//            } else {
//                log.error("wxPayError:{},{}", JSON.toJSONString(wxPayOrderNotifyResult), JSON.toJSONString(wxPayOrderNotifyResult));
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        return new BaseResult.Builder<String>().build();
    }

    @ApiOperation("微信支付退款结果通知")
    @PostMapping("/wxPayReturnResult")
    @ResponseBody
    public BaseResult<String> wxPayReturnResult(@RequestBody String json) {
        log.info("wxPayTest:{}", json);
        return new BaseResult.Builder<String>().build();
    }

    @ApiOperation("获取订单列表")
    @PostMapping("/getOrders")
    @ResponseBody
    public BaseResult<List<OrderResultVO>> getOrders(@RequestParam Long userId) {
//        List<BaseWxOrder> baseWxOrders = baseWxOrderMapper.selectOrderByUserId(userId);
//        if (CollUtil.isEmpty(baseWxOrders)) {
//            return new BaseResult.Builder<List<OrderResultVO>>().setData(new ArrayList<>()).build();
//        }
//        List<OrderResultVO> collect = baseWxOrders.stream().map(t -> {
//            OrderResultVO orderResultVo = new OrderResultVO();
//            MedicalMembershipCard medicalMembershipCard = medicalMembershipCardMapper.selectById(t.getUserOrderId());
//            BeanUtils.copyProperties(t, orderResultVo);
//            orderResultVo.setTitle(medicalMembershipCard.getTitle());
//            // 1分转化为0.01元
//            orderResultVo.setTotal(String.valueOf(Double.parseDouble(t.getTotal())));
//            orderResultVo.setPayerTotal(String.valueOf(Double.parseDouble(t.getPayerTotal())));
//            return orderResultVo;
//        }).collect(Collectors.toList());
        return new BaseResult.Builder<List<OrderResultVO>>().setData(null).build();
    }


    @ApiOperation("微信扫描记录接口")
    @PostMapping("/wxScanRecord")
    @ResponseBody
    public BaseResult<String> wxScanRecord(@RequestBody String json) {
        log.info("wxScanRecord:{}", json);
        return new BaseResult.Builder<String>().setData("success").build();
    }
}
